-
-
Notifications
You must be signed in to change notification settings - Fork 234
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
quaternion improvements and new features #43
Conversation
* the quaternion is used as right matrix
* because it must be unit quaternion and didn't specified this in docs. * we must provide alternative func for unit quat
* add SSE2 version and optimize scalar version
I implemented in "Alternative Method" mentioned in: http://www.euclideanspace.com/maths/geometry/rotations/conversions/matrixToQuaternion/index.htm quaternion.w = sqrt( max( 0, 1 + m00 + m11 + m22 ) ) / 2;
quaternion.x = sqrt( max( 0, 1 + m00 - m11 - m22 ) ) / 2;
quaternion.y = sqrt( max( 0, 1 - m00 + m11 - m22 ) ) / 2;
quaternion.z = sqrt( max( 0, 1 - m00 - m11 + m22 ) ) / 2;
Q.x = _copysign( Q.x, m21 - m12 )
Q.y = _copysign( Q.y, m02 - m20 )
Q.z = _copysign( Q.z, m10 - m01 ) It requires extra I didn't compare performances between other method and this "alternative" method but since it is possible to write SIMD version I used this one. In the future we may change this if we find better approach... Also I found this one: https://d3cw3dd2w32x2b.cloudfront.net/wp-content/uploads/2015/01/matrix-to-quat.pdf which seems interesting but I didn't worke for me, I don't know. |
One another thing is that, glm don't normalize input quaternion if I read it correctly and I don't know why: https://github.com/g-truc/glm/blob/8390a77b3a278b15259e5ca6e67f7e41badc457b/glm/gtc/quaternion.inl#L619 We should normalize it, and maybe we should provide alternative function which accepts only unit vector. |
Should we change the order of quaternion members from |
* use this for normalizing vector
Update: I updated matrix to quat code, I was said that I used alternative method but it didn't work well in tests. So I switched to other one, I borrowed mat2quat from Apple's simd library which works well and passes all tests. |
switching quat members to xyzw would be consistent with some other math libraries I've used, and my own internal ones. 👍 |
@shakesoda thanks for your feedback[s] 🤗, I thought the same, most libraries use xyzw and making cglm that way would make easier to copy quaternion from one library to another. Especially new-comers may assume that cglm uses xyzw (it is wxyz for now) but if they construct quaternion manually they will create wrong one and get wrong rotation matrix... wxyz perfectly matches with math expression (w + xi + yj + zk) but I'll change/update it to xyzw in this PR 👍 because in GLSL-like lang/apis quat.w is last element... One another thing I want to get feedback is that I want to change Alternative names: or we just continue to use PS: I dropped "alternative method" but I created a gist (https://gist.github.com/recp/97d87c8b9c3fe8ac432a865dff3c783d) for it, in the future we may bring it back if we can fix it's numerical errors (probably we will not) |
* convert quaternion multiplication to xyzw * previous implementation may be wrong, wikipedia version implemented * implement SSE version
* provide quat_copy function
Here is the new lookat function:
it is similar to Also I postponed quaternion -> euler because we may change euler API later, check this issue: #30 |
* provide _to version for storing into another quat
Now we also have another option to rotate vectors: Quaternions! New option:
Previous options:
Also, added some tests for quaternions everthing looks good except I didn't add tests for slerp and lerp.
|
* glm_quat_rotate is better name to rotate transform matrix using quaternion. * we may use mat4_mulq in the future for another purpose e.g. left multiplication quat with matrix
@winduptoy IIRC we have discussed quat order before, I hope you caught WXYZ to XYZW changes and I hope you are ok with this too I added some tests (and lots of APIs) and everthing looks good, we have better quaternion APIs now. I'm going to merge this PR after updated docs and change version from v0.3.5 to v0.4.0 |
New functions:
glm_quat_mat4t(versor q, mat4 dest)
- convert quat to mat4 (transposed)glm_quat_mat3(versor q, mat3 dest)
- convert quat to mat3glm_quat_mat3t(versor q, mat3 dest)
- convert quat to mat3 (transposed)glm_mat4_quat(mat4 m, versor dest)
- convert mat4 to quatglm_mat3_quat(mat3 m, versor dest)
- convert mat3 to quatglm_quat_conjugate(versor q, versor dest)
glm_quat_inv(versor q, versor dest)
- inverse of quaternionquat_mulv
toquat_mul
(because we multiply quat with quat, not vector), we may usemulv
for multiply quat with vector (In Progress)glm_quat_axis(versor q, vec3 dest)
- get axis from quatfloat glm_quat_real(versor q)
- returns wfloat glm_quat_angle(versor q)
- get angle from quatglm_quat_imag(versor q, vec3 dest)
glm_quat_imagn(versor q, vec3 dest)
- normalized version of `_imagfloat glm_quat_imaglen(versor q)
glm_quat_add(versor p, versor q, versor dest)
glm_quat_sub(versor p, versor q, versor dest)
glm_quat_roatev(versor q, vec3 v, vec3 dest)
maybe)glm_quat_roate(versor q, mat4 transform, mat4 dest)
maybe)glm_quat_look(vec3 eye, versor ori, mat4 dest)
- create view matrix using quaternionglm_quat_for(vec3 dir, vec3 fwd, vec3 up, versor dest)
- creates quaternion for look rotation (source to dest point)New Helpers:
glm_vec4_sqrt(vec4 v, vec4 dest)
glm_vec_sqrt(vec3 v, vec3 dest)
glm_vec4_sign(vec4 v, vec4 dest)
glm_vec_sign(vec3 v, vec3 dest)
glm_vec_lerp(vec3 from, vec3 to, float t, vec3 dest)
glm_vec4_lerp(vec4 from, vec4 to, float t, vec4 dest)
float glm_lerp(float from, float to, float t)
[DROPPED] - [x]
glm_mat4_mulq(mat4 m, versor q, mat4 dest)
- multiply mat4 with quat; now we haveglm_quat_roate
for this purpose[DROPPED] - [x]
glm_mat4_quat_sse2(mat4 m, versor dest)
- convert mat4 to quat (SSE2 version)[DROPPED] - [x]
glm_quat_slerp_sse2(versor from, versor to, float t, versor dest)
- it seems it is not produce correct results, alsoglm_quat_slerp
version is improved and usingvec4
s no need to write manual SSE codes becausevec4
functions are optimized with SIMD functions[POSTPONED] - [ ]
float glm_quat_euler(versor q, vec3 eulXYZ)
- convert quat to euler angles[POSTPONED] - [ ]
float glm_euler_quat(vec3 eulXYZ, versor dest)
- convert euler angles to quatCRITICAL CHANGES:
glm_quat_mat4
andglm_quat_mat3
before convert to matrix (if this is not good idea, please let me know)glm_quat_mulv
toglm_quat_mul
and useglm_quat_mulv
for multiply quat with vector